package spirit;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class J02_Departments {
	
	// 1.JDBC 드라이버 불러오기
	// JDBC 드라이버는 데이터베이스에 연결해야 할
	// 필요가 있는 자바 클래스와 JDBC 드라이버 사이의
	// 계약을 정의하는 인터페이스들을 구현한 것
	// 드라이버는 jar 파일 형태로 배포
	// JDBC 드라이버를 불러오는 방법에는
	// 수동manual과  동적dynamic 이 있음
	// Class.forname("oracle.jdbc.driver.OracleDriver");
	// Class.forName(DRV);
	
	// forName 메서드는 ClassNotFoundException
	// 예외를 던지기 때문에 try - catch 블럭 안에 둬야함
	
	// 2.데이터베이스 연결하기
	// Connection 인터페이스느 데이터베이스
	// 연결객체를 위한 그릇(템플릿)임
	// 연결객체를 얻으려면 DriverManager클래스의
	// getConnection 메서드를 이용
	// getConnection 메서드는 앞의 고자ㅓㅇ에서
	// 메모리에 올려둔 드라이버를 찾고 
	// URL,USR,PWD를 통해 데이터베이스 서버에
	// 연결을 하고 그 결과를 Connection으로 반환
	
	// JDBC 연결시 사용하는 URL은 다음과 같음
	// jdbc: 프로토콜: 하위이름
	// jdbc:oracle:thin:@주소:포트:DB이름?user=아이디&amp;password=비밀번호	// amp 특수기호화
	// jdbc:mysql://주소/DB이름?user=아이디&password=비밀번호
	
	// 3.SQL 질의문 생성 및 실행
	// Statement, PreparedStatement 객체는
	// 실행할 SQL 질의문을 의미함
	// createStatement, preparedStatement 메서드를
	// 이용해서 위 객체를 얻을 수 있음
	// 단, 메서드를 호출할떄에는  SQL 질의문을
	// 인자로 전달해야 함 
	// 생성한 객체를 실행하려면 executeQuery나
	// executeupdate 메서드를 이요함
	// executeQuery : SQL 질의문이 select 인 경우
	// executeupdate : insert, update, delete,
	//				   create, alter, drop 인 경우
	
	// executeUpdate의 실행결과는 질의문에 의해
	// 변경/삭제된 레코드 수나 0을 반환
	// executeQuery의 실행결과는 질의문에 의해
	// 생성된 데이터를 다암두는 Resultset 객체를 반환
	// 단 , 생성된 데이터가 없는 경우 null은 아님
	// Statement 에서 파생된 PreparedStatement는
	// statement의 인기있는 대체제임
	// SQL 문을 미리 컴파일하고 저장해두기 떄문에 
	// 추후 동일한 SQL문을 실행할 경우 빠르게 
	// 처리된다는 있는 장점이 제공
	
	// 4.결과집합 ResultSet 객체 다루기
	// 결과집합은 Statement, PrepartedStatement에서
	// 반환된 데이터베이스 테이블을 의미함
	// 결과집합 객체는 현재 데이터 행을 가리키는
	// 커서를 가지고 있음
	// 커서는 처음에는 테이블을 가리키고 있따가
	// next 메서드가 호출되면 첫번째 레코드로
	// 이동하고 true 또는 false를 반환함
	// true 가 반횐되면 현재 레코드가 존재한다는 의미
	// false 가 반환되면 더 이상 레코드가 없다는 의미
	// while을 이용해서 모든 레코드에  접근할 수 있음
	// next 메서드로 레코드에 접근한 뒤, 각 필드 값을
	// 가져오려면 getXxx 메서드를 사용해야 함
	// 일반적으로 필드 값을 문자열로 가져오는
	// getString 메서드를 많이 사용
	// 필드값을 int 로 가져오려면 getInt를 사용 하면 됨
	
	// getXxx 메서드에 필드이름 또는 필드 위치값을
	// 인자로 전달해서 필드값을  가져올수 있음
	// getString(1)
	// getString("department_id")
	
	// 5.JDBC 객체 닫기
	// 모든 JDBC 객체는 사용한 후 그들의 close 메서드를
	// 호출해서  항상 닫아야 함 
	//try{
	// ... ...
	// ... ... 
	// rs.close();
	// pstmt.close();
	// conn.close();
	// }catch(Exception ex){
	//   ex.printStarkTrace();
	// }
	// 위 코드는 완벽하지 않음
	// pstmt.close(); 가 실패하는 경우,
	// 그 아래 코드는 실행되지 않기 때문임
	// 따라서,close 관련 코드는  finally 절에 이들
	
	// 즉, 예외가 발생하든 하지 않든 간에
	// 무조건 실행되어야 하는 코드는 finnally 절에
	// 작성하면 프로그램이 다소 완벽해짐 
	
	public static void main(String args[]){
		
		final String DRV = "oracle.jdbc.driver.OracleDriver";
		final String URL = "jdbc:oracle:thin:@112.216.253.125:1521:xe";
		final String USR = "spirit";
		final String PWD = "spirit";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String SQL = "select * from departments";
		
		
		try{
			Class.forName(DRV);
			conn = DriverManager.getConnection(URL,USR,PWD);
			pstmt = conn.prepareStatement(SQL);
			rs = pstmt.executeQuery();
			
			if(rs.next()){
				do{
					System.out.println(rs.getString("department_id"));
					System.out.println(rs.getString("department_name"));
					
				}while(rs.next());
			}else {
				System.out.println("데이터가 없어");
			}
		}catch(Exception ex){
				ex.printStackTrace();
			}finally{
				if(rs != null)try{ rs.close(); rs = null;}catch(Exception e){}
				if(pstmt != null)try{ pstmt.close(); pstmt = null;}catch(Exception e){}
				if(conn != null)try{ conn.close(); conn = null;}catch(Exception e){}
			}
	}
}

